#include "server.h"
#include <iostream>
#include <boost/bind.hpp>
#include <vector>
#include <cstring>
#include <fstream>

Server::Server(boost::asio::io_context& io_context, short port)
    : acceptor_(io_context, tcp::endpoint(tcp::v4(), port)),
      socket_(io_context) {
    start_accept();
}

void Server::start_accept() {
    acceptor_.async_accept(socket_,
        boost::bind(&Server::handle_accept, this,
        boost::asio::placeholders::error));
}

void Server::handle_accept(const boost::system::error_code& error) {
    if (!error) {
        std::cout << "Connection accepted!" << std::endl;
        start_receive();
    } else {
        std::cerr << "Error in accepting connection: " << error.message() << std::endl;
    }
}

void Server::start_receive() {
    socket_.async_read_some(boost::asio::buffer(data_, max_length),
        boost::bind(&Server::handle_receive, this,
        boost::asio::placeholders::error,
        boost::asio::placeholders::bytes_transferred));
}

void Server::handle_receive(const boost::system::error_code& error, size_t bytes_transferred) {
    if (!error) {
        // 将接收到的字节数据存储在向量中
        std::vector<uint8_t> received_data(data_, data_ + bytes_transferred);

        if (received_data.size() == sizeof(int64_t) + sizeof(int) + sizeof(double) + sizeof(int)) {
            int64_t timestamp;
            int current_measurement;
            double speed;
            int dir;

            std::memcpy(&timestamp, &received_data[0], sizeof(int64_t));
            std::memcpy(&current_measurement, &received_data[sizeof(int64_t)], sizeof(int));
            std::memcpy(&speed, &received_data[sizeof(int64_t) + sizeof(int)], sizeof(double));
            std::memcpy(&dir, &received_data[sizeof(int64_t) + sizeof(int) + sizeof(double)], sizeof(int));

            std::cout << "Timestamp: " << timestamp << std::endl;
            std::cout << "Current Measurement: " << current_measurement << std::endl;
            std::cout << "Speed: " << speed << std::endl;
            std::cout << "Direction: " << dir << std::endl;
            save_to_csv(timestamp, current_measurement, speed, dir);
        } else {
            std::cerr << "Received data format is incorrect" << std::endl;
        }
        start_receive();
    } else {
        std::cerr << "Error in receiving data: " << error.message() << std::endl;
    }
}

void Server::save_to_csv(int64_t timestamp, int measurement, double speed, int dir)
{
    std::ifstream infile(filename);
    if (infile.good())
    {
        std::ofstream file(filename, std::ios::app);
        if (file.is_open())
        {
            file << timestamp << "," << measurement << "," << speed << "," << dir << "\n";
        }
        else
        {
            std::cerr << "Error opening file to save data" << std::endl;
        }
    }
}

void Server::ensure_file_exists(const char* file_name)
{
    filename = file_name;
    std::ifstream infile(file_name);
    if (!infile.good())
    {
        std::ofstream file(file_name, std::ios::app);
        if (file.is_open())
        {
            file << "Timestamp,Distance (cm),Speed (m/s),dir(0 down 1 up)\n";
        }
    }
}
